diff --git a/server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java index 3b72c082e0a..3d375c879a0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java @@ -158,13 +158,14 @@ private static void setBranchStatus(ProjectBranches.Branch.Builder builder, Bran ProjectBranches.Status.Builder statusBuilder = ProjectBranches.Status.newBuilder(); if (qualityGateMeasure != null) { Protobuf.setNullable(qualityGateMeasure.getDataAsString(), statusBuilder::setQualityGateStatus); + builder.setStatus(statusBuilder); } if (branch.getBranchType() == BranchType.SHORT) { statusBuilder.setBugs(branchStatistics == null ? 0L : branchStatistics.getBugs()); statusBuilder.setVulnerabilities(branchStatistics == null ? 0L : branchStatistics.getVulnerabilities()); statusBuilder.setCodeSmells(branchStatistics == null ? 0L : branchStatistics.getCodeSmells()); + builder.setStatus(statusBuilder); } - builder.setStatus(statusBuilder); } private void checkPermission(ComponentDto component) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java index 801dd6ffa73..f77b6e65ee8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java @@ -34,14 +34,12 @@ public final class ShortLivingBranchQualityGate { public static final long ID = -1_963_456_987L; public static final String NAME = "Hardcoded short living branch quality gate"; public static final List CONDITIONS = ImmutableList.of( - new Condition(CoreMetrics.BUGS_KEY, OPERATOR_GREATER_THAN, "0", false), - new Condition(CoreMetrics.VULNERABILITIES_KEY, OPERATOR_GREATER_THAN, "0", false), - new Condition(CoreMetrics.CODE_SMELLS_KEY, OPERATOR_GREATER_THAN, "0", false)); + new Condition(CoreMetrics.OPEN_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false), + new Condition(CoreMetrics.REOPENED_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false)); public static final QualityGate GATE = new QualityGate(String.valueOf(ID), NAME, ImmutableSet.of( - new org.sonar.server.qualitygate.Condition(CoreMetrics.BUGS_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false), - new org.sonar.server.qualitygate.Condition(CoreMetrics.VULNERABILITIES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false), - new org.sonar.server.qualitygate.Condition(CoreMetrics.CODE_SMELLS_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false))); + new org.sonar.server.qualitygate.Condition(CoreMetrics.OPEN_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false), + new org.sonar.server.qualitygate.Condition(CoreMetrics.REOPENED_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false))); private ShortLivingBranchQualityGate() { // prevents instantiation diff --git a/server/sonar-server/src/main/resources/org/sonar/server/branch/ws/list-example.json b/server/sonar-server/src/main/resources/org/sonar/server/branch/ws/list-example.json index 9d285888732..5fa613fe94d 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/branch/ws/list-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/branch/ws/list-example.json @@ -4,6 +4,9 @@ "name": "feature/bar", "isMain": false, "type": "LONG", + "status": { + "qualityGateStatus": "OK" + }, "analysisDate": "2017-04-01T01:15:42+0100" }, { @@ -11,6 +14,12 @@ "isMain": false, "type": "SHORT", "mergeBranch": "feature/bar", + "status": { + "qualityGateStatus": "OK", + "bugs": 1, + "vulnerabilities": 0, + "codeSmells": 0 + }, "analysisDate": "2017-04-03T13:37:00+0100" } ] diff --git a/server/sonar-server/src/test/java/org/sonar/server/branch/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/branch/ws/ListActionTest.java index 07307f29e77..3fff8eb8430 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/branch/ws/ListActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/branch/ws/ListActionTest.java @@ -28,7 +28,6 @@ import org.sonar.api.resources.ResourceTypes; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; @@ -47,7 +46,7 @@ import org.sonar.server.permission.index.PermissionIndexerTester; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; -import org.sonarqube.ws.Common; +import org.sonarqube.ws.Common.BranchType; import org.sonarqube.ws.MediaTypes; import org.sonarqube.ws.ProjectBranches; import org.sonarqube.ws.ProjectBranches.Branch; @@ -66,6 +65,7 @@ import static org.sonar.api.rules.RuleType.VULNERABILITY; import static org.sonar.api.utils.DateUtils.dateToLong; import static org.sonar.api.utils.DateUtils.parseDateTime; +import static org.sonar.api.web.UserRole.USER; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; import static org.sonar.db.component.BranchType.LONG; import static org.sonar.db.component.BranchType.SHORT; @@ -111,17 +111,25 @@ public void test_definition() { @Test public void test_example() { ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey("sonarqube")); + ComponentDto longLivingBranch = db.components() .insertProjectBranch(project, b -> b.setKey("feature/bar").setBranchType(LONG)); - ComponentDto shortLivingBranch = db.components() - .insertProjectBranch(project, b -> b.setKey("feature/foo").setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); - userSession.logIn().addProjectPermission(UserRole.USER, project); - db.getDbClient().snapshotDao().insert(db.getSession(), newAnalysis(longLivingBranch).setLast(true).setCreatedAt(parseDateTime("2017-04-01T01:15:42+0100").getTime())); + db.measures().insertLiveMeasure(longLivingBranch, qualityGateStatus, m -> m.setData("OK")); + + ComponentDto shortLivingBranch = db.components() + .insertProjectBranch(project, b -> b.setKey("feature/foo").setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); db.getDbClient().snapshotDao().insert(db.getSession(), newAnalysis(shortLivingBranch).setLast(true).setCreatedAt(parseDateTime("2017-04-03T13:37:00+0100").getTime())); - db.commit(); + db.measures().insertLiveMeasure(shortLivingBranch, qualityGateStatus, m -> m.setData("OK")); + + RuleDefinitionDto rule = db.rules().insert(); + db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(BUG).setResolution(null)); + + issueIndexer.indexOnStartup(emptySet()); + + userSession.logIn().addProjectPermission(USER, project); String json = ws.newRequest() .setParam("project", project.getDbKey()) @@ -129,21 +137,30 @@ public void test_example() { .getInput(); assertJson(json).isSimilarTo(ws.getDef().responseExampleAsString()); + assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(json); } @Test public void test_with_SCAN_EXCUTION_permission() { ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey("sonarqube")); - ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setKey("feature/bar").setBranchType(LONG)); - ComponentDto shortLivingBranch = db.components().insertProjectBranch(project, - b -> b.setKey("feature/foo").setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); - userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); + ComponentDto longLivingBranch = db.components() + .insertProjectBranch(project, b -> b.setKey("feature/bar").setBranchType(LONG)); db.getDbClient().snapshotDao().insert(db.getSession(), newAnalysis(longLivingBranch).setLast(true).setCreatedAt(parseDateTime("2017-04-01T01:15:42+0100").getTime())); + db.measures().insertLiveMeasure(longLivingBranch, qualityGateStatus, m -> m.setData("OK")); + + ComponentDto shortLivingBranch = db.components() + .insertProjectBranch(project, b -> b.setKey("feature/foo").setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); db.getDbClient().snapshotDao().insert(db.getSession(), newAnalysis(shortLivingBranch).setLast(true).setCreatedAt(parseDateTime("2017-04-03T13:37:00+0100").getTime())); - db.commit(); + db.measures().insertLiveMeasure(shortLivingBranch, qualityGateStatus, m -> m.setData("OK")); + + RuleDefinitionDto rule = db.rules().insert(); + db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(BUG).setResolution(null)); + issueIndexer.indexOnStartup(emptySet()); + + userSession.logIn().addProjectPermission(SCAN_EXECUTION, project); String json = ws.newRequest() .setParam("project", project.getDbKey()) @@ -156,7 +173,7 @@ public void test_with_SCAN_EXCUTION_permission() { @Test public void main_branch() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ListWsResponse response = ws.newRequest() .setParam("project", project.getDbKey()) @@ -164,14 +181,14 @@ public void main_branch() { assertThat(response.getBranchesList()) .extracting(Branch::getName, Branch::getIsMain, Branch::getType) - .containsExactlyInAnyOrder(tuple("master", true, Common.BranchType.LONG)); + .containsExactlyInAnyOrder(tuple("master", true, BranchType.LONG)); } @Test public void main_branch_with_specified_name() { OrganizationDto organization = db.organizations().insert(); ComponentDto project = db.components().insertMainBranch(organization, "head"); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ListWsResponse response = ws.newRequest() .setParam("project", project.getDbKey()) @@ -179,13 +196,13 @@ public void main_branch_with_specified_name() { assertThat(response.getBranchesList()) .extracting(Branch::getName, Branch::getIsMain, Branch::getType) - .containsExactlyInAnyOrder(tuple("head", true, Common.BranchType.LONG)); + .containsExactlyInAnyOrder(tuple("head", true, BranchType.LONG)); } @Test public void test_project_with_zero_branches() { ComponentDto project = db.components().insertPrivateProject(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); String json = ws.newRequest() .setParam("project", project.getDbKey()) @@ -200,7 +217,7 @@ public void test_project_with_branches() { ComponentDto project = db.components().insertMainBranch(); db.components().insertProjectBranch(project, b -> b.setKey("feature/bar")); db.components().insertProjectBranch(project, b -> b.setKey("feature/foo")); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ListWsResponse response = ws.newRequest() .setParam("project", project.getDbKey()) @@ -209,15 +226,15 @@ public void test_project_with_branches() { assertThat(response.getBranchesList()) .extracting(Branch::getName, Branch::getType) .containsExactlyInAnyOrder( - tuple("master", Common.BranchType.LONG), - tuple("feature/foo", Common.BranchType.LONG), - tuple("feature/bar", Common.BranchType.LONG)); + tuple("master", BranchType.LONG), + tuple("feature/foo", BranchType.LONG), + tuple("feature/bar", BranchType.LONG)); } @Test public void short_living_branches() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setKey("long").setBranchType(LONG)); ComponentDto shortLivingBranch = db.components().insertProjectBranch(project, @@ -232,16 +249,16 @@ public void short_living_branches() { assertThat(response.getBranchesList()) .extracting(Branch::getName, Branch::getType, Branch::getMergeBranch) .containsExactlyInAnyOrder( - tuple("master", Common.BranchType.LONG, ""), - tuple(longLivingBranch.getBranch(), Common.BranchType.LONG, ""), - tuple(shortLivingBranch.getBranch(), Common.BranchType.SHORT, longLivingBranch.getBranch()), - tuple(shortLivingBranchOnMaster.getBranch(), Common.BranchType.SHORT, "master")); + tuple("master", BranchType.LONG, ""), + tuple(longLivingBranch.getBranch(), BranchType.LONG, ""), + tuple(shortLivingBranch.getBranch(), BranchType.SHORT, longLivingBranch.getBranch()), + tuple(shortLivingBranchOnMaster.getBranch(), BranchType.SHORT, "master")); } @Test public void mergeBranch_is_using_default_main_name_when_main_branch_has_no_name() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto shortLivingBranch = db.components().insertProjectBranch(project, b -> b.setKey("short").setBranchType(SHORT).setMergeBranchUuid(project.uuid())); @@ -251,13 +268,13 @@ public void mergeBranch_is_using_default_main_name_when_main_branch_has_no_name( assertThat(response.getBranch()) .extracting(Branch::getName, Branch::getType, Branch::getMergeBranch) - .containsExactlyInAnyOrder(shortLivingBranch.getBranch(), Common.BranchType.SHORT, "master"); + .containsExactlyInAnyOrder(shortLivingBranch.getBranch(), BranchType.SHORT, "master"); } @Test public void short_living_branch_on_removed_branch() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto shortLivingBranch = db.components().insertProjectBranch(project, b -> b.setKey("short").setBranchType(SHORT).setMergeBranchUuid("unknown")); @@ -268,14 +285,14 @@ public void short_living_branch_on_removed_branch() { assertThat(response.getBranchesList()) .extracting(Branch::getName, Branch::getType, Branch::hasMergeBranch, Branch::getIsOrphan) .containsExactlyInAnyOrder( - tuple("master", Common.BranchType.LONG, false, false), - tuple(shortLivingBranch.getBranch(), Common.BranchType.SHORT, false, true)); + tuple("master", BranchType.LONG, false, false), + tuple(shortLivingBranch.getBranch(), BranchType.SHORT, false, true)); } @Test public void status_on_long_living_branch() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG)); db.measures().insertLiveMeasure(branch, qualityGateStatus, m -> m.setData("OK")); @@ -291,7 +308,7 @@ public void status_on_long_living_branch() { @Test public void status_on_short_living_branches() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG)); ComponentDto shortLivingBranch = db.components().insertProjectBranch(project, b -> b.setKey("short").setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); @@ -329,7 +346,7 @@ public void status_on_short_living_branches() { @Test public void status_on_short_living_branch_with_no_issue() { ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG)); db.components().insertProjectBranch(project, b -> b.setBranchType(SHORT).setMergeBranchUuid(longLivingBranch.uuid())); issueIndexer.indexOnStartup(emptySet()); @@ -339,7 +356,7 @@ public void status_on_short_living_branch_with_no_issue() { .setParam("project", project.getKey()) .executeProtobuf(ListWsResponse.class); - assertThat(response.getBranchesList().stream().filter(b -> b.getType().equals(Common.BranchType.SHORT)).map(ProjectBranches.Branch::getStatus)) + assertThat(response.getBranchesList().stream().filter(b -> b.getType().equals(BranchType.SHORT)).map(ProjectBranches.Branch::getStatus)) .extracting(Status::getBugs, Status::getVulnerabilities, Status::getCodeSmells) .containsExactlyInAnyOrder(tuple(0L, 0L, 0L)); } @@ -351,7 +368,7 @@ public void response_contains_date_of_last_analysis() { Long lastAnalysisShortLivingBranch = dateToLong(parseDateTime("2017-04-03T00:00:00+0100")); ComponentDto project = db.components().insertMainBranch(); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto shortLivingBranch1 = db.components().insertProjectBranch(project, b -> b.setBranchType(SHORT).setMergeBranchUuid(project.uuid())); ComponentDto longLivingBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(LONG)); ComponentDto shortLivingBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(SHORT).setMergeBranchUuid(longLivingBranch2.uuid())); @@ -373,17 +390,17 @@ public void response_contains_date_of_last_analysis() { .extracting(ProjectBranches.Branch::getType, ProjectBranches.Branch::hasAnalysisDate, b -> "".equals(b.getAnalysisDate()) ? null : dateToLong(parseDateTime(b.getAnalysisDate()))) .containsExactlyInAnyOrder( - tuple(Common.BranchType.LONG, false, null), - tuple(Common.BranchType.SHORT, false, null), - tuple(Common.BranchType.LONG, true, lastAnalysisLongLivingBranch), - tuple(Common.BranchType.SHORT, true, lastAnalysisShortLivingBranch)); + tuple(BranchType.LONG, false, null), + tuple(BranchType.SHORT, false, null), + tuple(BranchType.LONG, true, lastAnalysisLongLivingBranch), + tuple(BranchType.SHORT, true, lastAnalysisShortLivingBranch)); } @Test public void fail_when_using_branch_db_key() throws Exception { OrganizationDto organization = db.organizations().insert(); ComponentDto project = db.components().insertMainBranch(organization); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); ComponentDto branch = db.components().insertProjectBranch(project); expectedException.expect(NotFoundException.class); @@ -406,7 +423,7 @@ public void fail_if_missing_project_parameter() { public void fail_if_not_a_reference_on_project() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project)); - userSession.logIn().addProjectPermission(UserRole.USER, project); + userSession.logIn().addProjectPermission(USER, project); expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Invalid project key"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java index 531cce9de79..10b62b9f898 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java @@ -127,6 +127,8 @@ public void findById_of_hardcoded_short_living_branch_returns_hardcoded_qp() { MetricImpl bugsMetric = mockMetricInRepository(CoreMetrics.BUGS_KEY); MetricImpl vulnerabilitiesMetric = mockMetricInRepository(CoreMetrics.VULNERABILITIES_KEY); MetricImpl codeSmellsMetric = mockMetricInRepository(CoreMetrics.CODE_SMELLS_KEY); + MetricImpl openedIssueMetric = mockMetricInRepository(CoreMetrics.OPEN_ISSUES_KEY); + MetricImpl reOpenedIssueMetric = mockMetricInRepository(CoreMetrics.REOPENED_ISSUES_KEY); Optional res = underTest.findById(ShortLivingBranchQualityGate.ID); @@ -137,9 +139,8 @@ public void findById_of_hardcoded_short_living_branch_returns_hardcoded_qp() { assertThat(qualityGate.getConditions()) .extracting(Condition::getMetric, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarningThreshold, Condition::hasPeriod) .containsOnly( - tuple(bugsMetric, GREATER_THAN, "0", null, false), - tuple(vulnerabilitiesMetric, GREATER_THAN, "0", null, false), - tuple(codeSmellsMetric, GREATER_THAN, "0", null, false)); + tuple(openedIssueMetric, GREATER_THAN, "0", null, false), + tuple(reOpenedIssueMetric, GREATER_THAN, "0", null, false)); } private MetricImpl mockMetricInRepository(String metricKey) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java index e72211727ba..3f4ad722b67 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java @@ -27,14 +27,14 @@ import static org.assertj.core.api.Assertions.tuple; public class ShortLivingBranchQualityGateTest { + @Test - public void defines_3_conditions() { + public void defines_short_living_branches_hardcoded_quality_gate_conditions() { assertThat(ShortLivingBranchQualityGate.CONDITIONS) .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarnThreshold, Condition::isOnLeak) .containsExactly( - tuple(CoreMetrics.BUGS_KEY, "GT", "0", null, false), - tuple(CoreMetrics.VULNERABILITIES_KEY, "GT", "0", null, false), - tuple(CoreMetrics.CODE_SMELLS_KEY, "GT", "0", null, false)); + tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0", null, false), + tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0", null, false)); } }