]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10457 Short living branch quality guate is based only on open & reopen issues
authorGuillaume Jambet <guillaume.jambet@sonarsource.com>
Mon, 5 Mar 2018 17:16:28 +0000 (18:16 +0100)
committerGuillaume Jambet <guillaume.jambet@gmail.com>
Wed, 14 Mar 2018 12:30:35 +0000 (13:30 +0100)
server/sonar-server/src/main/java/org/sonar/server/branch/ws/ListAction.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java
server/sonar-server/src/main/resources/org/sonar/server/branch/ws/list-example.json
server/sonar-server/src/test/java/org/sonar/server/branch/ws/ListActionTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitygate/QualityGateServiceImplTest.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java

index 3b72c082e0a7819c58cfcb0e85892a9adea99b07..3d375c879a0469830251a8e27b06aec6faabbc9e 100644 (file)
@@ -158,13 +158,14 @@ public class ListAction implements BranchWsAction {
     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) {
index 801dd6ffa7387dc1108a29b22402bd72835c30a8..f77b6e65ee8485eed7d0df4157675c5372813129 100644 (file)
@@ -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<Condition> 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
index 9d285888732504b7d08ea636f827cec303b08b02..5fa613fe94df55b938eaed7529ab4d2b1a974681 100644 (file)
@@ -4,6 +4,9 @@
       "name": "feature/bar",
       "isMain": false,
       "type": "LONG",
+      "status": {
+        "qualityGateStatus": "OK"
+      },
       "analysisDate": "2017-04-01T01:15:42+0100"
     },
     {
       "isMain": false,
       "type": "SHORT",
       "mergeBranch": "feature/bar",
+      "status": {
+        "qualityGateStatus": "OK",
+        "bugs": 1,
+        "vulnerabilities": 0,
+        "codeSmells": 0
+      },
       "analysisDate": "2017-04-03T13:37:00+0100"
     }
   ]
index 07307f29e772cdffa9a9195f930772f3795da492..3fff8eb843030bba00380966bd5f7d380f2abc34 100644 (file)
@@ -28,7 +28,6 @@ import org.sonar.api.config.internal.MapSettings;
 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.AuthorizationTypeSupport;
 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.CODE_SMELL;
 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 class ListActionTest {
   @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 class ListActionTest {
       .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 class ListActionTest {
   @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 class ListActionTest {
 
     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 class ListActionTest {
 
     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 class ListActionTest {
     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 class ListActionTest {
     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 class ListActionTest {
     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 class ListActionTest {
 
     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 class ListActionTest {
     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 class ListActionTest {
   @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 class ListActionTest {
   @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 class ListActionTest {
       .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 class ListActionTest {
     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 class ListActionTest {
       .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 class ListActionTest {
   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");
index 531cce9de791f914cf0a9e63dbca167ed55acb8d..10b62b9f898ecb462eda6f2f53824ae8c4d3104f 100644 (file)
@@ -127,6 +127,8 @@ public class QualityGateServiceImplTest {
     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<QualityGate> res = underTest.findById(ShortLivingBranchQualityGate.ID);
 
@@ -137,9 +139,8 @@ public class QualityGateServiceImplTest {
     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) {
index e72211727baa4d11f2adec454124f973a29d6868..3f4ad722b67d247bcb8974adbf617c83ac8f70c2 100644 (file)
@@ -27,14 +27,14 @@ import static org.assertj.core.api.Assertions.assertThat;
 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));
   }
 
 }