diff options
36 files changed, 670 insertions, 128 deletions
diff --git a/it/it-tests/src/test/java/it/Category1Suite.java b/it/it-tests/src/test/java/it/Category1Suite.java index cfb7fca2c1a..959c0fd4565 100644 --- a/it/it-tests/src/test/java/it/Category1Suite.java +++ b/it/it-tests/src/test/java/it/Category1Suite.java @@ -32,11 +32,9 @@ import it.authorisation.SystemAdminPermissionTest; import it.customMeasure.CustomMeasuresTest; import it.i18n.I18nTest; import it.measure.MeasuresWsTest; -import it.measure.NewDebtRatioMeasureTest; import it.measure.ProjectMeasuresPageTest; import it.measure.ProjectOverviewTest; import it.measure.ProjectWidgetsTest; -import it.measure.TechnicalDebtMeasureVariationTest; import it.measureFilter.MeasureFiltersTest; import it.measureHistory.DifferentialPeriodsTest; import it.measureHistory.HistoryUiTest; @@ -49,6 +47,8 @@ import it.projectAdministration.ProjectAdministrationTest; import it.qualityGate.QualityGateNotificationTest; import it.qualityGate.QualityGateTest; import it.qualityGate.QualityGateUiTest; +import it.qualityModel.NewDebtRatioMeasureTest; +import it.qualityModel.TechnicalDebtMeasureVariationTest; import it.settings.PropertySetsTest; import it.settings.SettingsTest; import it.settings.SubCategoriesTest; diff --git a/it/it-tests/src/test/java/it/Category2Suite.java b/it/it-tests/src/test/java/it/Category2Suite.java index 6183bca5c32..7a2eee1527a 100644 --- a/it/it-tests/src/test/java/it/Category2Suite.java +++ b/it/it-tests/src/test/java/it/Category2Suite.java @@ -20,12 +20,6 @@ package it; import com.sonar.orchestrator.Orchestrator; -import it.debt.SqaleRatingMeasureTest; -import it.debt.TechnicalDebtInIssueChangelogTest; -import it.debt.TechnicalDebtMeasureTest; -import it.debt.TechnicalDebtPurgeTest; -import it.debt.TechnicalDebtTest; -import it.debt.TechnicalDebtWidgetTest; import it.issue.AutoAssignTest; import it.issue.CommonRulesTest; import it.issue.CustomRulesTest; @@ -41,6 +35,12 @@ import it.issue.IssueWorkflowTest; import it.issue.ManualIssueRelocationTest; import it.issue.ManualIssueTest; import it.issue.NewIssuesMeasureTest; +import it.qualityModel.MaintainabilityMeasureTest; +import it.qualityModel.MaintainabilityRatingMeasureTest; +import it.qualityModel.TechnicalDebtInIssueChangelogTest; +import it.qualityModel.TechnicalDebtPurgeTest; +import it.qualityModel.TechnicalDebtTest; +import it.qualityModel.TechnicalDebtWidgetTest; import it.rule.ManualRulesTest; import it.test.CoverageTest; import it.test.CoverageTrackingTest; @@ -79,9 +79,9 @@ import static util.ItUtils.xooPlugin; // rule ManualRulesTest.class, // debt - SqaleRatingMeasureTest.class, + MaintainabilityRatingMeasureTest.class, TechnicalDebtInIssueChangelogTest.class, - TechnicalDebtMeasureTest.class, + MaintainabilityMeasureTest.class, TechnicalDebtPurgeTest.class, TechnicalDebtTest.class, TechnicalDebtWidgetTest.class diff --git a/it/it-tests/src/test/java/it/debt/TechnicalDebtMeasureTest.java b/it/it-tests/src/test/java/it/debt/TechnicalDebtMeasureTest.java deleted file mode 100644 index 71f4f47c575..00000000000 --- a/it/it-tests/src/test/java/it/debt/TechnicalDebtMeasureTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package it.debt; - -import com.sonar.orchestrator.Orchestrator; -import com.sonar.orchestrator.build.SonarRunner; -import com.sonar.orchestrator.locator.FileLocation; -import it.Category2Suite; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.sonar.wsclient.services.Measure; -import org.sonar.wsclient.services.Resource; -import org.sonar.wsclient.services.ResourceQuery; - -import static org.assertj.core.api.Assertions.assertThat; -import static util.ItUtils.projectDir; - -/** - * SONAR-4715 - */ -public class TechnicalDebtMeasureTest { - - private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; - private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a"; - private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"; - private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1"; - private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo"; - private static final String TECHNICAL_DEBT_MEASURE = "sqale_index"; - @ClassRule - public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; - - @BeforeClass - public static void init() { - orchestrator.resetData(); - - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); - orchestrator.getServer().provisionProject(PROJECT, PROJECT); - orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); - orchestrator.executeBuild(SonarRunner.create(projectDir("shared/xoo-multi-modules-sample"))); - } - - @Test - public void technical_debt_measures() { - assertThat(getMeasure(PROJECT, TECHNICAL_DEBT_MEASURE).getValue()).isEqualTo(445); - assertThat(getMeasure(MODULE, TECHNICAL_DEBT_MEASURE).getValue()).isEqualTo(231); - assertThat(getMeasure(SUB_MODULE, TECHNICAL_DEBT_MEASURE).getValue()).isEqualTo(113); - assertThat(getMeasure(DIRECTORY, TECHNICAL_DEBT_MEASURE).getValue()).isEqualTo(28); - assertThat(getMeasure(FILE, TECHNICAL_DEBT_MEASURE).getValue()).isEqualTo(28); - } - - private Measure getMeasure(String resource, String metricKey) { - Resource res = orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(resource, metricKey)); - if (res == null) { - return null; - } - return res.getMeasure(metricKey); - } -} diff --git a/it/it-tests/src/test/java/it/issue/IssueSearchTest.java b/it/it-tests/src/test/java/it/issue/IssueSearchTest.java index 0945578c2d0..a3155f2c641 100644 --- a/it/it-tests/src/test/java/it/issue/IssueSearchTest.java +++ b/it/it-tests/src/test/java/it/issue/IssueSearchTest.java @@ -19,11 +19,13 @@ */ package it.issue; +import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.sonar.orchestrator.locator.FileLocation; import com.sonar.orchestrator.selenium.Selenese; +import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; @@ -43,9 +45,14 @@ import org.sonar.wsclient.issue.IssueQuery; import org.sonar.wsclient.issue.Issues; import org.sonar.wsclient.issue.NewActionPlan; import org.sonar.wsclient.issue.NewIssue; +import org.sonarqube.ws.Common; +import org.sonarqube.ws.MediaTypes; +import org.sonarqube.ws.client.GetRequest; +import org.sonarqube.ws.client.WsResponse; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; +import static util.ItUtils.newAdminWsClient; import static util.ItUtils.runProjectAnalysis; import static util.ItUtils.setServerProperty; import static util.ItUtils.toDate; @@ -57,7 +64,7 @@ public class IssueSearchTest extends AbstractIssueTest { private static final String PROJECT_KEY2 = "com.sonarsource.it.samples:multi-modules-sample2"; private static int DEFAULT_PAGINATED_RESULTS = 100; - private static int TOTAL_NB_ISSUES = 143; + private static int TOTAL_NB_ISSUES = 273; @BeforeClass public static void prepareData() { @@ -102,9 +109,9 @@ public class IssueSearchTest extends AbstractIssueTest { @Test public void search_issues_by_component_roots() { - assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample")).list()).hasSize(72); - assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a")).list()).hasSize(44); - assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1")).list()).hasSize(20); + assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample")).list()).hasSize(DEFAULT_PAGINATED_RESULTS); + assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a")).list()).hasSize(83); + assertThat(search(IssueQuery.create().componentRoots("com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1")).list()).hasSize(37); assertThat(search(IssueQuery.create().componentRoots("unknown")).list()).isEmpty(); } @@ -113,15 +120,15 @@ public class IssueSearchTest extends AbstractIssueTest { public void search_issues_by_components() { assertThat( search(IssueQuery.create().components("com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo")).list()) - .hasSize(19); + .hasSize(35); assertThat(search(IssueQuery.create().components("unknown")).list()).isEmpty(); } @Test public void search_issues_by_severities() { - assertThat(search(IssueQuery.create().severities("BLOCKER")).list()).isEmpty(); + assertThat(search(IssueQuery.create().severities("BLOCKER")).list()).hasSize(8); assertThat(search(IssueQuery.create().severities("CRITICAL")).list()).hasSize(9); - assertThat(search(IssueQuery.create().severities("MAJOR")).list()).hasSize(8); + assertThat(search(IssueQuery.create().severities("MAJOR")).list()).hasSize(DEFAULT_PAGINATED_RESULTS); assertThat(search(IssueQuery.create().severities("MINOR")).list()).hasSize(DEFAULT_PAGINATED_RESULTS); assertThat(search(IssueQuery.create().severities("INFO")).list()).hasSize(4); } @@ -239,7 +246,7 @@ public class IssueSearchTest extends AbstractIssueTest { Paging paging = issues.paging(); assertThat(paging.pageIndex()).isEqualTo(2); assertThat(paging.pageSize()).isEqualTo(20); - assertThat(paging.total()).isEqualTo(143); + assertThat(paging.total()).isEqualTo(TOTAL_NB_ISSUES); // SONAR-3257 // return max page size results when using negative page size value @@ -249,11 +256,10 @@ public class IssueSearchTest extends AbstractIssueTest { @Test public void sort_results() { - // 9 issue in CRITICAL (including the manual one), following ones are in MAJOR List<Issue> issues = search(IssueQuery.create().sort("SEVERITY").asc(false)).list(); - assertThat(issues.get(0).severity()).isEqualTo("CRITICAL"); + assertThat(issues.get(0).severity()).isEqualTo("BLOCKER"); assertThat(issues.get(8).severity()).isEqualTo("CRITICAL"); - assertThat(issues.get(9).severity()).isEqualTo("MAJOR"); + assertThat(issues.get(17).severity()).isEqualTo("MAJOR"); } /** @@ -315,6 +321,34 @@ public class IssueSearchTest extends AbstractIssueTest { ).build()); } + @Test + public void return_issue_type() throws Exception { + List<org.sonarqube.ws.Issues.Issue> issues = searchByRuleKey("xoo:OneBugIssuePerLine"); + assertThat(issues).isNotEmpty(); + org.sonarqube.ws.Issues.Issue issue = issues.get(0); + assertThat(issue.getType()).isEqualTo(Common.RuleType.BUG); + + issues = searchByRuleKey("xoo:OneVulnerabilityIssuePerModule"); + assertThat(issues).isNotEmpty(); + issue = issues.get(0); + assertThat(issue.getType()).isEqualTo(Common.RuleType.VULNERABILITY); + + issues = searchByRuleKey("xoo:OneIssuePerLine"); + assertThat(issues).isNotEmpty(); + issue = issues.get(0); + assertThat(issue.getType()).isEqualTo(Common.RuleType.CODE_SMELL); + } + + private List<org.sonarqube.ws.Issues.Issue> searchByRuleKey(String... ruleKey) throws IOException { + WsResponse response = newAdminWsClient(ORCHESTRATOR) + .wsConnector() + .call(new GetRequest("api/issues/search") + .setParam("rules", Joiner.on(",").join(ruleKey)) + .setMediaType(MediaTypes.PROTOBUF)); + org.sonarqube.ws.Issues.SearchWsResponse searchWsResponse = org.sonarqube.ws.Issues.SearchWsResponse.parseFrom(response.contentStream()); + return searchWsResponse.getIssuesList(); + } + private static Component findComponent(Collection<Component> components, final String key) { return Iterables.find(components, new Predicate<Component>() { @Override diff --git a/it/it-tests/src/test/java/it/debt/DebtConfigurationRule.java b/it/it-tests/src/test/java/it/qualityModel/DebtConfigurationRule.java index 18d68e81b2e..8fb4a12a84a 100644 --- a/it/it-tests/src/test/java/it/debt/DebtConfigurationRule.java +++ b/it/it-tests/src/test/java/it/qualityModel/DebtConfigurationRule.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; diff --git a/it/it-tests/src/test/java/it/qualityModel/MaintainabilityMeasureTest.java b/it/it-tests/src/test/java/it/qualityModel/MaintainabilityMeasureTest.java new file mode 100644 index 00000000000..18e8034a172 --- /dev/null +++ b/it/it-tests/src/test/java/it/qualityModel/MaintainabilityMeasureTest.java @@ -0,0 +1,120 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.qualityModel; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarScanner; +import com.sonar.orchestrator.locator.FileLocation; +import it.Category2Suite; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; + +/** + * SONAR-4715 + */ +public class MaintainabilityMeasureTest { + + private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; + private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a"; + private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"; + private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1"; + private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo"; + + private static final String CODE_SMELLS_METRIC = "code_smells"; + private static final String MAINTAINABILITY_REMEDIATION_EFFORT_METRIC = "sqale_index"; + private static final String MAINTAINABILITY_RATING_METRIC = "sqale_rating"; + private static final String EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC = "effort_to_reach_maintainability_rating_a"; + + @ClassRule + public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + + @Rule + public DebtConfigurationRule debtConfiguration = DebtConfigurationRule.create(orchestrator); + + @Before + public void init() { + orchestrator.resetData(); + + // Set rating grid values to not depend from default value + debtConfiguration.updateRatingGrid(0.1d, 0.2d, 0.5d, 1d); + + orchestrator.getServer().provisionProject(PROJECT, PROJECT); + } + + @Test + public void verify_maintainability_measures_when_code_smells_rules_activated() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, CODE_SMELLS_METRIC).getValue()).isEqualTo(71); + assertThat(getMeasure(PROJECT, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getValue()).isEqualTo(445); + assertThat(getMeasure(PROJECT, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("C"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC).getValue()).isEqualTo(292); + + assertThat(getMeasure(MODULE, CODE_SMELLS_METRIC).getValue()).isEqualTo(43); + assertThat(getMeasure(MODULE, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getValue()).isEqualTo(231); + assertThat(getMeasure(MODULE, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("C"); + assertThat(getMeasure(MODULE, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC).getValue()).isEqualTo(150); + + assertThat(getMeasure(SUB_MODULE, CODE_SMELLS_METRIC).getValue()).isEqualTo(19); + assertThat(getMeasure(SUB_MODULE, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getValue()).isEqualTo(113); + assertThat(getMeasure(SUB_MODULE, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("C"); + assertThat(getMeasure(SUB_MODULE, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC).getValue()).isEqualTo(77); + + assertThat(getMeasure(DIRECTORY, CODE_SMELLS_METRIC).getValue()).isEqualTo(18); + assertThat(getMeasure(DIRECTORY, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getValue()).isEqualTo(28); + assertThat(getMeasure(DIRECTORY, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(DIRECTORY, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC).getValue()).isEqualTo(0); + + assertThat(getMeasure(FILE, CODE_SMELLS_METRIC).getValue()).isEqualTo(18); + assertThat(getMeasure(FILE, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getValue()).isEqualTo(28); + assertThat(getMeasure(FILE, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(FILE, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC)).isNull(); + } + + @Test + public void verify_reliability_measures_when_no_code_smells_rule() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/without-type-code-smells.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "without-type-code-smells"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, CODE_SMELLS_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, MAINTAINABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, MAINTAINABILITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(0); + } + + private Measure getMeasure(String resource, String metricKey) { + Resource res = orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(resource, metricKey)); + if (res == null) { + return null; + } + return res.getMeasure(metricKey); + } +} diff --git a/it/it-tests/src/test/java/it/debt/SqaleRatingMeasureTest.java b/it/it-tests/src/test/java/it/qualityModel/MaintainabilityRatingMeasureTest.java index db88173d763..89e861b1941 100644 --- a/it/it-tests/src/test/java/it/debt/SqaleRatingMeasureTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/MaintainabilityRatingMeasureTest.java @@ -17,12 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; import com.sonar.orchestrator.locator.FileLocation; import it.Category2Suite; +import javax.annotation.CheckForNull; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; @@ -37,7 +38,7 @@ import static util.ItUtils.projectDir; /** * SONAR-4715 */ -public class SqaleRatingMeasureTest { +public class MaintainabilityRatingMeasureTest { private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a"; @@ -61,7 +62,7 @@ public class SqaleRatingMeasureTest { @Test public void sqale_rating_measures() { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); orchestrator.getServer().provisionProject(PROJECT, PROJECT); orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); @@ -85,7 +86,7 @@ public class SqaleRatingMeasureTest { @Test public void sqale_debt_ratio_measures() { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); orchestrator.getServer().provisionProject(PROJECT, PROJECT); orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); @@ -100,7 +101,7 @@ public class SqaleRatingMeasureTest { @Test public void use_development_cost_parameter() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-line.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-line.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); @@ -120,7 +121,7 @@ public class SqaleRatingMeasureTest { @Test public void use_language_specific_parameters() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-line.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-line.xml")); orchestrator.getServer().provisionProject(PROJECT, PROJECT); orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "one-issue-per-line"); @@ -142,7 +143,7 @@ public class SqaleRatingMeasureTest { @Test public void use_rating_grid_parameter() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-line.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-line.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); @@ -162,7 +163,7 @@ public class SqaleRatingMeasureTest { @Test public void effort_to_reach_maintainability_rating_a() { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); orchestrator.getServer().provisionProject(PROJECT, PROJECT); orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); @@ -185,6 +186,7 @@ public class SqaleRatingMeasureTest { assertThat(getMeasure(FILE, "effort_to_reach_maintainability_rating_a")).isNull(); } + @CheckForNull private Measure getMeasure(String resource, String metricKey) { Resource res = orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(resource, metricKey)); if (res == null) { diff --git a/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java b/it/it-tests/src/test/java/it/qualityModel/NewDebtRatioMeasureTest.java index d6198be3e97..01bb6359be0 100644 --- a/it/it-tests/src/test/java/it/measure/NewDebtRatioMeasureTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/NewDebtRatioMeasureTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.measure; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.locator.FileLocation; diff --git a/it/it-tests/src/test/java/it/qualityModel/ReliabilityMeasureTest.java b/it/it-tests/src/test/java/it/qualityModel/ReliabilityMeasureTest.java new file mode 100644 index 00000000000..c04376cc9c0 --- /dev/null +++ b/it/it-tests/src/test/java/it/qualityModel/ReliabilityMeasureTest.java @@ -0,0 +1,112 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.qualityModel; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarScanner; +import com.sonar.orchestrator.locator.FileLocation; +import it.Category2Suite; +import javax.annotation.CheckForNull; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; + +public class ReliabilityMeasureTest { + + private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; + private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a"; + private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"; + private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1"; + private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo"; + + private static final String BUGS_METRIC = "bugs"; + private static final String RELIABILITY_REMEDIATION_EFFORT_METRIC = "reliability_remediation_effort"; + private static final String RELIABILITY_RATING_METRIC = "reliability_rating"; + private static final String EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC = "effort_to_reach_reliability_rating_a"; + + @ClassRule + public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + + @Before + public void init() { + orchestrator.resetData(); + + orchestrator.getServer().provisionProject(PROJECT, PROJECT); + } + + @Test + public void verify_reliability_measures_when_bug_rules_activated() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, BUGS_METRIC).getIntValue()).isEqualTo(61); + assertThat(getMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(305); + assertThat(getMeasure(PROJECT, RELIABILITY_RATING_METRIC).getData()).isEqualTo("D"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(305); + + assertThat(getMeasure(MODULE, BUGS_METRIC).getIntValue()).isEqualTo(37); + assertThat(getMeasure(MODULE, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(185); + assertThat(getMeasure(MODULE, RELIABILITY_RATING_METRIC).getData()).isEqualTo("D"); + assertThat(getMeasure(MODULE, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(185); + + assertThat(getMeasure(SUB_MODULE, BUGS_METRIC).getIntValue()).isEqualTo(16); + assertThat(getMeasure(SUB_MODULE, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(80); + assertThat(getMeasure(SUB_MODULE, RELIABILITY_RATING_METRIC).getData()).isEqualTo("D"); + assertThat(getMeasure(SUB_MODULE, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(80); + + assertThat(getMeasure(DIRECTORY, BUGS_METRIC).getIntValue()).isEqualTo(16); + assertThat(getMeasure(DIRECTORY, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(80); + assertThat(getMeasure(DIRECTORY, RELIABILITY_RATING_METRIC).getData()).isEqualTo("D"); + assertThat(getMeasure(DIRECTORY, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(80); + + assertThat(getMeasure(FILE, BUGS_METRIC).getIntValue()).isEqualTo(16); + assertThat(getMeasure(FILE, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(80); + assertThat(getMeasure(FILE, RELIABILITY_RATING_METRIC).getData()).isEqualTo("D"); + assertThat(getMeasure(FILE, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(80); + } + + @Test + public void verify_reliability_measures_when_no_bug_rule() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/without-type-bug.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "without-type-bug"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, BUGS_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, RELIABILITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, RELIABILITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_RELIABILITY_RATING_A_METRIC).getIntValue()).isEqualTo(0); + } + + @CheckForNull + private Measure getMeasure(String resource, String metricKey) { + Resource res = orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(resource, metricKey)); + if (res == null) { + return null; + } + return res.getMeasure(metricKey); + } +} diff --git a/it/it-tests/src/test/java/it/qualityModel/SecurityMeasureTest.java b/it/it-tests/src/test/java/it/qualityModel/SecurityMeasureTest.java new file mode 100644 index 00000000000..4aeda0ae762 --- /dev/null +++ b/it/it-tests/src/test/java/it/qualityModel/SecurityMeasureTest.java @@ -0,0 +1,112 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package it.qualityModel; + +import com.sonar.orchestrator.Orchestrator; +import com.sonar.orchestrator.build.SonarScanner; +import com.sonar.orchestrator.locator.FileLocation; +import it.Category2Suite; +import javax.annotation.CheckForNull; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.wsclient.services.Measure; +import org.sonar.wsclient.services.Resource; +import org.sonar.wsclient.services.ResourceQuery; + +import static org.assertj.core.api.Assertions.assertThat; +import static util.ItUtils.projectDir; + +public class SecurityMeasureTest { + + private static final String PROJECT = "com.sonarsource.it.samples:multi-modules-sample"; + private static final String MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a"; + private static final String SUB_MODULE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"; + private static final String DIRECTORY = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1"; + private static final String FILE = "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo"; + + private static final String VULNERABILITIES_METRIC = "vulnerabilities"; + private static final String SECURITY_REMEDIATION_EFFORT_METRIC = "security_remediation_effort"; + private static final String SECURITY_RATING_METRIC = "security_rating"; + private static final String EFFORT_TO_REACH_SECURITY_RATING_A_METRIC = "effort_to_reach_security_rating_a"; + + @ClassRule + public static Orchestrator orchestrator = Category2Suite.ORCHESTRATOR; + + @Before + public void init() { + orchestrator.resetData(); + + orchestrator.getServer().provisionProject(PROJECT, PROJECT); + } + + @Test + public void verify_security_measures_when_vulnerability_rules_activated() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "with-many-rules"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, VULNERABILITIES_METRIC).getIntValue()).isEqualTo(4); + assertThat(getMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(340); + assertThat(getMeasure(PROJECT, SECURITY_RATING_METRIC).getData()).isEqualTo("E"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC).getIntValue()).isEqualTo(340); + + assertThat(getMeasure(MODULE, VULNERABILITIES_METRIC).getIntValue()).isEqualTo(2); + assertThat(getMeasure(MODULE, SECURITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(170); + assertThat(getMeasure(MODULE, SECURITY_RATING_METRIC).getData()).isEqualTo("E"); + assertThat(getMeasure(MODULE, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC).getIntValue()).isEqualTo(170); + + assertThat(getMeasure(SUB_MODULE, VULNERABILITIES_METRIC).getIntValue()).isEqualTo(1); + assertThat(getMeasure(SUB_MODULE, SECURITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(85); + assertThat(getMeasure(SUB_MODULE, SECURITY_RATING_METRIC).getData()).isEqualTo("E"); + assertThat(getMeasure(SUB_MODULE, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC).getIntValue()).isEqualTo(85); + + assertThat(getMeasure(DIRECTORY, VULNERABILITIES_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(DIRECTORY, SECURITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(DIRECTORY, SECURITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(DIRECTORY, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC).getIntValue()).isEqualTo(0); + + assertThat(getMeasure(FILE, VULNERABILITIES_METRIC)).isNull(); + assertThat(getMeasure(FILE, SECURITY_REMEDIATION_EFFORT_METRIC)).isNull(); + assertThat(getMeasure(FILE, SECURITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(FILE, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC)).isNull(); + } + + @Test + public void verify_security_measures_when_no_vulnerability_rule() { + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/without-type-vulnerability.xml")); + orchestrator.getServer().associateProjectToQualityProfile(PROJECT, "xoo", "without-type-vulnerability"); + orchestrator.executeBuild(SonarScanner.create(projectDir("shared/xoo-multi-modules-sample"))); + + assertThat(getMeasure(PROJECT, VULNERABILITIES_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, SECURITY_REMEDIATION_EFFORT_METRIC).getIntValue()).isEqualTo(0); + assertThat(getMeasure(PROJECT, SECURITY_RATING_METRIC).getData()).isEqualTo("A"); + assertThat(getMeasure(PROJECT, EFFORT_TO_REACH_SECURITY_RATING_A_METRIC).getIntValue()).isEqualTo(0); + } + + @CheckForNull + private Measure getMeasure(String resource, String metricKey) { + Resource res = orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(resource, metricKey)); + if (res == null) { + return null; + } + return res.getMeasure(metricKey); + } +} diff --git a/it/it-tests/src/test/java/it/debt/TechnicalDebtInIssueChangelogTest.java b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtInIssueChangelogTest.java index 8df76ad0b7a..a1584523c31 100644 --- a/it/it-tests/src/test/java/it/debt/TechnicalDebtInIssueChangelogTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtInIssueChangelogTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; @@ -61,7 +61,7 @@ public class TechnicalDebtInIssueChangelogTest { @Test public void display_debt_in_issue_changelog() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-file.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-file.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-file"); @@ -88,7 +88,7 @@ public class TechnicalDebtInIssueChangelogTest { @Test public void use_hours_in_day_property_to_display_debt_in_issue_changelog() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-file.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-file.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-file"); diff --git a/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtMeasureVariationTest.java index f5369071e94..12b52584144 100644 --- a/it/it-tests/src/test/java/it/measure/TechnicalDebtMeasureVariationTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtMeasureVariationTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.measure; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.locator.FileLocation; diff --git a/it/it-tests/src/test/java/it/debt/TechnicalDebtPurgeTest.java b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtPurgeTest.java index 9ee0febd76e..d16b347a383 100644 --- a/it/it-tests/src/test/java/it/debt/TechnicalDebtPurgeTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtPurgeTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; @@ -48,7 +48,7 @@ public class TechnicalDebtPurgeTest { public void resetData() throws Exception { orchestrator.resetData(); - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); orchestrator.getServer().provisionProject("com.sonarsource.it.samples:multi-modules-sample", "com.sonarsource.it.samples:multi-modules-sample"); orchestrator.getServer().associateProjectToQualityProfile("com.sonarsource.it.samples:multi-modules-sample", "xoo", "with-many-rules"); } diff --git a/it/it-tests/src/test/java/it/debt/TechnicalDebtTest.java b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtTest.java index 6c2b03b9e12..0acb73e58b2 100644 --- a/it/it-tests/src/test/java/it/debt/TechnicalDebtTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; @@ -56,7 +56,7 @@ public class TechnicalDebtTest { */ @Test public void technical_debt_on_issue() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-line.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-line.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line"); @@ -73,7 +73,7 @@ public class TechnicalDebtTest { @Test public void use_hours_in_day_property_to_display_debt() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-issue-per-file.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-issue-per-file.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-file"); @@ -93,7 +93,7 @@ public class TechnicalDebtTest { @Test public void use_hours_in_day_property_during_analysis_to_convert_debt() throws Exception { - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/one-day-debt-per-file.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/one-day-debt-per-file.xml")); orchestrator.getServer().provisionProject("sample", "sample"); orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-day-debt-per-file"); diff --git a/it/it-tests/src/test/java/it/debt/TechnicalDebtWidgetTest.java b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtWidgetTest.java index 72b93fdd451..989545d9ec9 100644 --- a/it/it-tests/src/test/java/it/debt/TechnicalDebtWidgetTest.java +++ b/it/it-tests/src/test/java/it/qualityModel/TechnicalDebtWidgetTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package it.debt; +package it.qualityModel; import com.sonar.orchestrator.Orchestrator; import com.sonar.orchestrator.build.SonarRunner; @@ -49,7 +49,7 @@ public class TechnicalDebtWidgetTest { // Set rating grid values to not depend from default value debtConfiguration.updateRatingGrid(0.1d, 0.2d, 0.5d, 1d); - orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/debt/with-many-rules.xml")); + orchestrator.getServer().restoreProfile(FileLocation.ofClasspath("/qualityModel/with-many-rules.xml")); orchestrator.getServer().provisionProject("com.sonarsource.it.samples:multi-modules-sample", "com.sonarsource.it.samples:multi-modules-sample"); orchestrator.getServer().associateProjectToQualityProfile("com.sonarsource.it.samples:multi-modules-sample", "xoo", "with-many-rules"); @@ -72,11 +72,11 @@ public class TechnicalDebtWidgetTest { public void technical_debt_in_issues_widget() { new SeleneseTest(Selenese.builder() .setHtmlTestsInClasspath("technical-debt-in-issues-widget", - "/debt/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html", - "/debt/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html", - "/debt/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html", + "/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html", + "/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html", + "/qualityModel/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html", // SONAR-4717 - "/debt/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html" + "/qualityModel/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html" ).build()).runOn(orchestrator); } @@ -87,9 +87,9 @@ public class TechnicalDebtWidgetTest { public void debt_overview_widget() { new SeleneseTest(Selenese.builder() .setHtmlTestsInClasspath("debt-overview-widget", - "/debt/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html", - "/debt/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html", - "/debt/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html" + "/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html", + "/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html", + "/qualityModel/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html" ).build()).runOn(orchestrator); } diff --git a/it/it-tests/src/test/resources/issue/with-many-rules.xml b/it/it-tests/src/test/resources/issue/with-many-rules.xml index a08c9cdd246..f97ef70cefd 100644 --- a/it/it-tests/src/test/resources/issue/with-many-rules.xml +++ b/it/it-tests/src/test/resources/issue/with-many-rules.xml @@ -28,5 +28,15 @@ </parameter> </parameters> </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneBugIssuePerLine</key> + <priority>MAJOR</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneVulnerabilityIssuePerModule</key> + <priority>BLOCKER</priority> + </rule> </rules> </profile> diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html index de5a4b33d1b..de5a4b33d1b 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/display-differential-values.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html index 6b7091b7662..6b7091b7662 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-have-correct-values.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html index 97a8cec43cc..97a8cec43cc 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/debt-overview/should-open-links-on-measures-service.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html index 53d098987af..53d098987af 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/display-differential-values.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html index 4d6e710e540..4d6e710e540 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/is-in-issues-widget.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html index fe9e416e7a4..fe9e416e7a4 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-have-correct-values.html diff --git a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html index 039266c60ee..039266c60ee 100644 --- a/it/it-tests/src/test/resources/debt/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html +++ b/it/it-tests/src/test/resources/qualityModel/TechnicalDebtWidgetTest/technical-debt/should-open-remediation-cost-on-measures-service.html diff --git a/it/it-tests/src/test/resources/debt/has-hello-tag.xml b/it/it-tests/src/test/resources/qualityModel/has-hello-tag.xml index 88cf4f9273e..88cf4f9273e 100644 --- a/it/it-tests/src/test/resources/debt/has-hello-tag.xml +++ b/it/it-tests/src/test/resources/qualityModel/has-hello-tag.xml diff --git a/it/it-tests/src/test/resources/debt/one-day-debt-per-file.xml b/it/it-tests/src/test/resources/qualityModel/one-day-debt-per-file.xml index cdebd7554c9..cdebd7554c9 100644 --- a/it/it-tests/src/test/resources/debt/one-day-debt-per-file.xml +++ b/it/it-tests/src/test/resources/qualityModel/one-day-debt-per-file.xml diff --git a/it/it-tests/src/test/resources/debt/one-issue-per-file.xml b/it/it-tests/src/test/resources/qualityModel/one-issue-per-file.xml index 7193ebfd779..7193ebfd779 100644 --- a/it/it-tests/src/test/resources/debt/one-issue-per-file.xml +++ b/it/it-tests/src/test/resources/qualityModel/one-issue-per-file.xml diff --git a/it/it-tests/src/test/resources/debt/one-issue-per-line.xml b/it/it-tests/src/test/resources/qualityModel/one-issue-per-line.xml index 521adc7e06f..521adc7e06f 100644 --- a/it/it-tests/src/test/resources/debt/one-issue-per-line.xml +++ b/it/it-tests/src/test/resources/qualityModel/one-issue-per-line.xml diff --git a/it/it-tests/src/test/resources/debt/with-many-rules.xml b/it/it-tests/src/test/resources/qualityModel/with-many-rules.xml index f3d0baf0616..6668eff9096 100644 --- a/it/it-tests/src/test/resources/debt/with-many-rules.xml +++ b/it/it-tests/src/test/resources/qualityModel/with-many-rules.xml @@ -28,5 +28,15 @@ </parameter> </parameters> </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneBugIssuePerLine</key> + <priority>CRITICAL</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneVulnerabilityIssuePerModule</key> + <priority>BLOCKER</priority> + </rule> </rules> -</profile>
\ No newline at end of file +</profile> diff --git a/it/it-tests/src/test/resources/qualityModel/without-type-bug.xml b/it/it-tests/src/test/resources/qualityModel/without-type-bug.xml new file mode 100644 index 00000000000..89c92cf10fa --- /dev/null +++ b/it/it-tests/src/test/resources/qualityModel/without-type-bug.xml @@ -0,0 +1,26 @@ +<profile> + <name>without-type-bug</name> + <language>xoo</language> + <rules> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerLine</key> + <priority>MINOR</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerFile</key> + <priority>MAJOR</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerModule</key> + <priority>CRITICAL</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneVulnerabilityIssuePerModule</key> + <priority>BLOCKER</priority> + </rule> + </rules> +</profile> diff --git a/it/it-tests/src/test/resources/qualityModel/without-type-code-smells.xml b/it/it-tests/src/test/resources/qualityModel/without-type-code-smells.xml new file mode 100644 index 00000000000..4bbb6f88ed7 --- /dev/null +++ b/it/it-tests/src/test/resources/qualityModel/without-type-code-smells.xml @@ -0,0 +1,16 @@ +<profile> + <name>without-type-code-smells</name> + <language>xoo</language> + <rules> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneBugIssuePerLine</key> + <priority>CRITICAL</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneVulnerabilityIssuePerModule</key> + <priority>BLOCKER</priority> + </rule> + </rules> +</profile> diff --git a/it/it-tests/src/test/resources/qualityModel/without-type-vulnerability.xml b/it/it-tests/src/test/resources/qualityModel/without-type-vulnerability.xml new file mode 100644 index 00000000000..c5fb823bd7c --- /dev/null +++ b/it/it-tests/src/test/resources/qualityModel/without-type-vulnerability.xml @@ -0,0 +1,26 @@ +<profile> + <name>without-type-vulnerability</name> + <language>xoo</language> + <rules> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerLine</key> + <priority>MINOR</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerFile</key> + <priority>MAJOR</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneIssuePerModule</key> + <priority>CRITICAL</priority> + </rule> + <rule> + <repositoryKey>xoo</repositoryKey> + <key>OneBugIssuePerLine</key> + <priority>CRITICAL</priority> + </rule> + </rules> +</profile> diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index ae8070e55b3..3da7721c448 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -39,11 +39,13 @@ import org.sonar.xoo.rule.DeprecatedResourceApiSensor; import org.sonar.xoo.rule.HasTagSensor; import org.sonar.xoo.rule.MultilineIssuesSensor; import org.sonar.xoo.rule.OneBlockerIssuePerFileSensor; +import org.sonar.xoo.rule.OneBugIssuePerLineSensor; import org.sonar.xoo.rule.OneDayDebtPerFileSensor; import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; import org.sonar.xoo.rule.OneIssuePerFileSensor; import org.sonar.xoo.rule.OneIssuePerLineSensor; import org.sonar.xoo.rule.OneIssuePerModuleSensor; +import org.sonar.xoo.rule.OneVulnerabilityIssuePerModuleSensor; import org.sonar.xoo.rule.RandomAccessSensor; import org.sonar.xoo.rule.Xoo2BasicProfile; import org.sonar.xoo.rule.XooBasicProfile; @@ -106,6 +108,9 @@ public class XooPlugin extends SonarPlugin { MultilineIssuesSensor.class, CustomMessageSensor.class, + OneBugIssuePerLineSensor.class, + OneVulnerabilityIssuePerModuleSensor.class, + // Coverage UtCoverageSensor.class, ItCoverageSensor.class, diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneBugIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneBugIssuePerLineSensor.java new file mode 100644 index 00000000000..92dac75eb8a --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneBugIssuePerLineSensor.java @@ -0,0 +1,73 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.rule; + +import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.xoo.Xoo; +import org.sonar.xoo.Xoo2; + +public class OneBugIssuePerLineSensor implements Sensor { + + public static final String RULE_KEY = "OneBugIssuePerLine"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("One Bug Issue Per Line") + .onlyOnLanguages(Xoo.KEY, Xoo2.KEY) + .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY, XooRulesDefinition.XOO2_REPOSITORY); + } + + @Override + public void execute(SensorContext context) { + analyse(context, Xoo.KEY, XooRulesDefinition.XOO_REPOSITORY); + } + + private void analyse(SensorContext context, String language, String repo) { + FileSystem fs = context.fileSystem(); + FilePredicates p = fs.predicates(); + for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(language), p.hasType(Type.MAIN)))) { + createIssues(file, context, repo); + } + } + + private void createIssues(InputFile file, SensorContext context, String repo) { + RuleKey ruleKey = RuleKey.of(repo, RULE_KEY); + for (int line = 1; line <= file.lines(); line++) { + NewIssue newIssue = context.newIssue(); + newIssue + .forRule(ruleKey) + .at(newIssue.newLocation() + .on(file) + .at(file.selectLine(line)) + .message("This bug issue is generated on each line")) + .save(); + } + } + +} diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneVulnerabilityIssuePerModuleSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneVulnerabilityIssuePerModuleSensor.java new file mode 100644 index 00000000000..8c21d46cf59 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneVulnerabilityIssuePerModuleSensor.java @@ -0,0 +1,57 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.rule; + +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.xoo.Xoo; + +public class OneVulnerabilityIssuePerModuleSensor implements Sensor { + + public static final String RULE_KEY = "OneVulnerabilityIssuePerModule"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("One Issue Per Module") + .onlyOnLanguages(Xoo.KEY) + .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY); + } + + @Override + public void execute(SensorContext context) { + analyse(context, XooRulesDefinition.XOO_REPOSITORY); + } + + private void analyse(SensorContext context, String repo) { + RuleKey ruleKey = RuleKey.of(repo, RULE_KEY); + NewIssue newIssue = context.newIssue(); + newIssue + .forRule(ruleKey) + .at(newIssue.newLocation() + .on(context.module()) + .message("This issue is generated on each module")) + .save(); + } + +} diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java index fd0bb0aa9ee..3233ab2d369 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java @@ -19,6 +19,7 @@ */ package org.sonar.xoo.rule; +import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; @@ -115,6 +116,20 @@ public class XooRulesDefinition implements RulesDefinition { repo.createRule(MultilineIssuesSensor.RULE_KEY).setName("Creates issues with ranges/multiple locations") .setHtmlDescription("Issue with range and multiple locations"); + NewRule oneBugIssuePerLine = repo.createRule(OneBugIssuePerLineSensor.RULE_KEY).setName("One Bug Issue Per Line") + .setHtmlDescription("Generate a bug issue on each line of a file. It requires the metric \"lines\".") + .setType(RuleType.BUG); + oneBugIssuePerLine + .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("5min")); + + NewRule oneVulnerabilityIssuePerModule = repo.createRule(OneVulnerabilityIssuePerModuleSensor.RULE_KEY).setName("One Vulnerability Issue Per Module") + .setHtmlDescription("Generate an issue on each module") + .setType(RuleType.VULNERABILITY); + oneVulnerabilityIssuePerModule + .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linearWithOffset("25min", "1h")) + .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " + + "then it's about one hour per module."); + repo.done(); } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java index 9da06081645..3f39fd0e271 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java @@ -42,7 +42,7 @@ public class XooRulesDefinitionTest { assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo"); assertThat(repo.language()).isEqualTo("xoo"); - assertThat(repo.rules()).hasSize(13); + assertThat(repo.rules()).hasSize(15); RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY); assertThat(rule.name()).isNotEmpty(); |